package com.ygqh.baby.controller.admin;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.ygqh.baby.annotation.SupplierLog;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.controller.utils.DocumentHandler;
import com.ygqh.baby.model.YgSkuInfo;
import com.ygqh.baby.po.*;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.JsonUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.*;

@Controller
@RequestMapping("/admin/store")
public class YgStoreController extends BaseController<Object, java.lang.Long> {

	@Autowired
	private YgSupplierService ygSupplierService;
	@Autowired
	private YgStoreService ygStoreService;
	@Autowired
	private YgSkuService ygSkuService;
	@Autowired
	private YgSkuSupplyPriceService ygSkuSupplyPriceService;
	@Autowired
	private FileService fileService;
	@Autowired
	private RedisDao redisDao;
	String KEY = "store";
	@Autowired
	private YgSupplierReconciliationService ygSupplierReconciliationService;

	@RequestMapping("searchSupplier")
	@ResponseBody
	public Map<String, Object> searchSupplier(String q, QueryInfo queryInfo) {

		ResultSet<YgSupplier> resultSet = ygSupplierService.search(queryInfo, q);

		return resultSet.toDatatables(null);
	}

	@RequestMapping("searchSupplierList")
	@ResponseBody
	public List<YgSupplier> searchSupplierList(String q) {

		List<YgSupplier> list = null;
		if (StringUtils.isNotBlank(redisDao.get(KEY))) {
			list = JSON.parseObject(redisDao.get(KEY), new TypeReference<List<YgSupplier>>() {
			});

		} else {
			list = ygSupplierService.find();
			redisDao.set(KEY, JSON.toJSONString(list), 0);
		}
		return list;
	}

	@SupplierLog(description = "新增/更新商家", params = { "supplier" })
	@RequestMapping("saveSupplier")
	@ResponseBody
	public Message saveSupplier(String supplier) {
		YgSupplier adSupplier = JsonUtils.toObject(supplier, YgSupplier.class);
		if (adSupplier.getId() != null) {
			adSupplier.setUpdateBy(getSession().getTrueName());
			adSupplier.setUpdateTime(new Date());
		} else {
			adSupplier.setCreateBy(getSession().getTrueName());
			adSupplier.setCreateTime(new Date());

		}
		// 判断供应商名称是否存在
		if (checkSupplierName(adSupplier.getSupplierName(), adSupplier.getId()) > 0)
			return Message.error("供应商名称不能重复");
		if (adSupplier.getSupplierType().equals("OnLine")) {
			// 新增时判断登录名是否已经存在
			if (adSupplier.getId() == null && checkLoginName(adSupplier.getLoginName()) > 0)
				return Message.error("登录名不能重复");
		}
		redisDao.set(KEY, "", -1);
		if (ygSupplierService.saveOrUpdate(adSupplier) == 1) {
			ygSupplierService.updateSupplierScheduleJob(adSupplier.getId());
			return Message.success(adSupplier.getId());
		}
		return ERROR_MESSAGE;
	}

	private int checkLoginName(String loginName) {
		return ygSupplierService.checkLoginName(loginName);

	}

	@SupplierLog(description = "删除商家", params = { "id" })
	@RequestMapping("delSupplier")
	@ResponseBody
	public Message delSupplier(Long id) {
		YgSupplier supplier = new YgSupplier();
		supplier.setId(id);
		supplier.setUpdateBy(getSession().getTrueName());
		supplier.setUpdateTime(new Date());
		redisDao.set(KEY, "", -1);
		return ygSupplierService.deleteSoft(supplier) == 1 ? SUCCESS_MESSAGE : ERROR_MESSAGE;
	}

	private int checkSupplierName(String supplierName, Long id) {
		return ygSupplierService.checkSupplierName(supplierName, id);
	}

	@RequestMapping("getSupplier")
	@ResponseBody
	public YgSupplier getSupplier(Long id) {

		return ygSupplierService.findById(id);

	}

	@RequestMapping("searchStoreList")
	@ResponseBody
	public List<YgStore> searchStoreList(String q) {
		List<YgStore> list = null;
		if (StringUtils.isNotBlank(redisDao.get(KEY))) {
			list = JSON.parseObject(redisDao.get(KEY), new TypeReference<List<YgStore>>() {
			});

		} else {
			list = ygStoreService.find();
			redisDao.set(KEY, JSON.toJSONString(list), 0);
		}
		return list;
	}

	@RequestMapping("searchSkuInfoList")
	@ResponseBody
	public Map<String, Object> getSkuInfoList(String q, QueryInfo info, String productCode, Long supplierId, Boolean hasSkuSupplierPrice) {
		ResultSet<YgSkuInfo> resultSet = ygSkuService.search(info, q, productCode, supplierId, hasSkuSupplierPrice);
		return resultSet.toDatatables(null);
	}

	@SupplierLog(description = "修改线下渠道供货价", params = { "supplierId", "skuSupplyPrice" })
	@RequestMapping("updateSkuSupplyPrice")
	@ResponseBody
	public Message updateSkuSupplyPrice(Long supplierId, String skuSupplyPrice) {
		YgSkuSupplyPrice ygSkuSupplyPrice = JsonUtils.toObject(skuSupplyPrice, YgSkuSupplyPrice.class);
		if (ygSkuSupplyPrice.getId() == null) {
			ygSkuSupplyPriceService.saveYgSkuSupply(ygSkuSupplyPrice);
		} else {
			ygSkuSupplyPriceService.updateYgSkuSupply(ygSkuSupplyPrice);
		}
		return Message.success(ygSkuSupplyPrice);
	}

	@SupplierLog(description = "批量修改线下渠道供货价", params = { "supplierId", "skuSupplyPrices" })
	@RequestMapping("batchUpdateSkuSupplyPrice")
	@ResponseBody
	public Message batchUpdateSkuSupplyPrice(Long supplierId, String skuSupplyPrices) {
		List<YgSkuSupplyPrice> list = JsonUtils.toObject(skuSupplyPrices, new com.fasterxml.jackson.core.type.TypeReference<List<YgSkuSupplyPrice>>() {
		});
		return ygSkuSupplyPriceService.saveYgSkuSupplyPriceBatch(list);
	}

	@SupplierLog(description = "修改线下渠道全部供货价", params = { "supplierId", "discountType", "discount", "q", "productCode" })
	@RequestMapping("updateAllSkuSupplyPrice")
	@ResponseBody
	public Message updateAllSkuSupplyPrice(Long supplierId, Boolean discountType, BigDecimal discount, String q, String productCode) {
		return ygSkuSupplyPriceService.updateAllSkuSupplyPrice(supplierId, discountType, discount, q, productCode);
	}

	@SuppressWarnings({ "resource" })
	@RequestMapping("readTemplate")
	@ResponseBody
	public Message readTemplate(@RequestParam("uploadFile") MultipartFile uploadFile, Long supplierId, HttpServletRequest request, HttpServletResponse respons)
			throws IOException {
		InputStream is = uploadFile.getInputStream();
		XSSFWorkbook xssfWorkbook = new XSSFWorkbook(is);
		List<YgSkuInfo> ygSkuInfos = new ArrayList<>();
		List<String> skuCodeList = new ArrayList<>();
		try {
			// Read the Sheet
			for (int numSheet = 0; numSheet < xssfWorkbook.getNumberOfSheets(); numSheet++) {
				XSSFSheet xssfSheet = xssfWorkbook.getSheetAt(numSheet);
				if (xssfSheet == null) {
					continue;
				}
				// Read the Row
				for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
					XSSFRow xssfRow = xssfSheet.getRow(rowNum);
					if (xssfRow != null) {
						YgSkuInfo model = new YgSkuInfo();
						DecimalFormat dfStr = new DecimalFormat("0");
						model.setProductCode(getValue(xssfRow.getCell(0), dfStr));
						model.setProductName(getValue(xssfRow.getCell(1), dfStr));
						model.setSkuCode(getValue(xssfRow.getCell(2), dfStr));
						model.setSizeName(getValue(xssfRow.getCell(3), dfStr));
						if (StringUtils.isBlank(model.getProductCode()) && StringUtils.isBlank(model.getProductName())
								&& StringUtils.isBlank(model.getSkuCode())) {
							continue;
						}
						DecimalFormat dfDb = new DecimalFormat("0.00");
						model.setSalesPrice(
								new BigDecimal(StringUtils.isEmpty(getValue(xssfRow.getCell(4), dfDb)) ? "0.00" : getValue(xssfRow.getCell(4), dfDb)));
						model.setCostPrice(
								new BigDecimal(StringUtils.isEmpty(getValue(xssfRow.getCell(5), dfDb)) ? "0.00" : getValue(xssfRow.getCell(5), dfDb)));
						model.setSupplyPrice(
								new BigDecimal(StringUtils.isEmpty(getValue(xssfRow.getCell(6), dfDb)) ? "0.00" : getValue(xssfRow.getCell(6), dfDb)));
						if (model.getSkuCode() == null) {
							model.setRemark("SKU不能为空");
						} else {
							if (skuCodeList.contains(model.getSkuCode())) {
								model.setRemark("SKU重复;");
							} else {
								skuCodeList.add(model.getSkuCode());
								YgSku sku = ygSkuService.findBySkuCode(model.getSkuCode(), PromotionType.Ordinary);
								if (sku == null) {
									model.setRemark("SKU不存在;");
								} else {
									model.setSkuId(sku.getId());
									YgSkuSupplyPrice findSkuSupplyPrice = ygSkuSupplyPriceService.findSkuSupplyPrice(sku.getId(), supplierId);
									if (findSkuSupplyPrice != null) {
										model.setSkuSupplyPriceId(findSkuSupplyPrice.getId());
									}
								}
							}
						}
						ygSkuInfos.add(model);
					}
				}
			}
			return Message.success(ygSkuInfos);
		} catch (Exception e) {
			return Message.error(ygSkuInfos);
		}

	}

	@SuppressWarnings("static-access")
	private String getValue(XSSFCell hssfCell, DecimalFormat df) {
		if (hssfCell == null)
			return null;
		if (hssfCell.getCellType() == hssfCell.CELL_TYPE_BOOLEAN) {
			// 返回布尔类型的值
			return String.valueOf(hssfCell.getBooleanCellValue());
		} else if (hssfCell.getCellType() == hssfCell.CELL_TYPE_NUMERIC) {
			String str = df.format(hssfCell.getNumericCellValue());
			// 返回数值类型的值
			return str;
		} else {
			// 返回字符串类型的值
			return String.valueOf(hssfCell.getStringCellValue());
		}
	}

	@RequestMapping("exportSupplier")
	public void exportSupplier(String q, String productCode, Long supplierId, HttpServletRequest request, HttpServletResponse response) {
		List<YgSkuInfo> skuInfoList = ygSkuService.getSkuInfoList(new QueryInfo(-1, 0), q, productCode, supplierId, Boolean.TRUE);
		byte[] bytes = fileService.downloadFromOss(FileTemplate.SupplyPriceExport.getCode());
		Map<String, Object> dataMap = new HashMap<String, Object>();
		dataMap.put("resultSet", skuInfoList);
		DocumentHandler.DownloadExcel(bytes, FileTemplate.SupplyPriceExport.getTitle(), dataMap, request, response);
	}

	@RequestMapping(value = "searchSupplierReconciliation")
	@ResponseBody
	public Map<String, Object> searchSupplierReconciliation(QueryInfo queryInfo, String q, @RequestParam Long supplierId, ContractStatus reconciliationStatus) {
		ResultSet<YgSupplierReconciliation> resultSet = ygSupplierReconciliationService.search(queryInfo, q, supplierId, reconciliationStatus);
		return resultSet.toDatatables(null);
	}

	@RequestMapping("exportSupplierReconciliation")
	public void exportSupplierReconciliation(@RequestParam Long reconciliationId, HttpServletRequest request, HttpServletResponse response) {
		Map<String, Object> dataMap = ygSupplierReconciliationService.findExportData(reconciliationId);
		byte[] bytes = fileService.downloadFromOss(FileTemplate.SupplyReconciliationExport.getCode());
		DocumentHandler.DownloadExcel(bytes, FileTemplate.SupplyReconciliationExport.getTitle(), dataMap, request, response);
	}
	
	@RequestMapping(value = "updateSupplierReconciliation")
	@ResponseBody
	public Message updateSupplierReconciliation(@RequestParam Long id, @RequestParam ContractStatus reconciliationStatus, String remark, BigDecimal reconciliationPrice) {
		YgSupplierReconciliation update = new YgSupplierReconciliation();
		update.setId(id);
		update.setReconciliationPrice(reconciliationPrice != null && reconciliationPrice.compareTo(BigDecimal.ZERO) == 0 ? null : reconciliationPrice);
		update.setReconciliationStatus(reconciliationStatus);
		update.setRemark(remark);
		update.setReconciliationBy(getSession().getTrueName());
		update.setReconciliationTime(new Date());
		int row = ygSupplierReconciliationService.update(update);
		if (row > 0) {
			return SUCCESS_MESSAGE;
		}
		return ERROR_MESSAGE;
	}

	@RequestMapping(value = "resetSupplierReconciliantion")
	@ResponseBody
	public Message resetSupplierReconciliantion(@RequestParam Long id) {
		try {
			ygSupplierReconciliationService.updateByReset(id);
		} catch (Exception e) {
			return Message.error(e.getMessage(), null);
		}
		return SUCCESS_MESSAGE;
	}

}
